package com.sy.simpleegg.platform.whmhex

import android.content.Context
import android.util.Log
import com.sy.simpleegg.app.App
import com.sy.simpleegg.constant.Constant
import com.sy.simpleegg.ext.logFile
import com.sy.simpleegg.platform.whmhex.bean.WhmHexGoodBean
import com.sy.simpleegg.platform.whmhex.bean.WhmHexPayTypeBean
import com.sy.simpleegg.platform.whmhex.config.WhmHexDevType
import com.sy.simpleegg.util.BoardApiUtil
import com.sy.simpleegg.util.GsonUtil
import com.sy.logger.Logger
import com.sy.mqhexsdk.WhmMqHexHplper
import com.sy.mqhexsdk.bean.CashDataBean
import com.sy.mqhexsdk.bean.CoinsDataBean
import com.sy.mqhexsdk.bean.NetInfo
import com.sy.mqhexsdk.bean.SignalInfo
import com.sy.mqhexsdk.bean.rec.RecAppVerResp
import com.sy.mqhexsdk.bean.rec.RecCashDataResp
import com.sy.mqhexsdk.bean.rec.RecChannelGoodInfo
import com.sy.mqhexsdk.bean.rec.RecChannelGoodOrder
import com.sy.mqhexsdk.bean.rec.RecChannelParamResp
import com.sy.mqhexsdk.bean.rec.RecCheckChannel
import com.sy.mqhexsdk.bean.rec.RecCheckOrder
import com.sy.mqhexsdk.bean.rec.RecCmdNumberData
import com.sy.mqhexsdk.bean.rec.RecCmdNumberDataResp
import com.sy.mqhexsdk.bean.rec.RecCodePayResult
import com.sy.mqhexsdk.bean.rec.RecDevConsumeWalletResp
import com.sy.mqhexsdk.bean.rec.RecDevQrCode
import com.sy.mqhexsdk.bean.rec.RecDevSaveWalletResp
import com.sy.mqhexsdk.bean.rec.RecDeviceErrStateResp
import com.sy.mqhexsdk.bean.rec.RecDeviceStateResp
import com.sy.mqhexsdk.bean.rec.RecDownloadFile
import com.sy.mqhexsdk.bean.rec.RecForceUpgrade
import com.sy.mqhexsdk.bean.rec.RecFuncListInfo
import com.sy.mqhexsdk.bean.rec.RecGoodSingle
import com.sy.mqhexsdk.bean.rec.RecGoodStockResp
import com.sy.mqhexsdk.bean.rec.RecHeartBeatResult
import com.sy.mqhexsdk.bean.rec.RecLogCommand
import com.sy.mqhexsdk.bean.rec.RecLoginResult
import com.sy.mqhexsdk.bean.rec.RecLogoutResp
import com.sy.mqhexsdk.bean.rec.RecOrder
import com.sy.mqhexsdk.bean.rec.RecPackageByIdInfo
import com.sy.mqhexsdk.bean.rec.RecPackageInfo
import com.sy.mqhexsdk.bean.rec.RecPackageUpdate
import com.sy.mqhexsdk.bean.rec.RecPayCode
import com.sy.mqhexsdk.bean.rec.RecPayTypeList
import com.sy.mqhexsdk.bean.rec.RecReboot
import com.sy.mqhexsdk.bean.rec.RecReloadChannelGood
import com.sy.mqhexsdk.bean.rec.RecReverseDataResp
import com.sy.mqhexsdk.bean.rec.RecSaveCoinsResp
import com.sy.mqhexsdk.bean.rec.RecShopInfo
import com.sy.mqhexsdk.bean.rec.RecSwipeCardDataResp
import com.sy.mqhexsdk.bean.rec.RecTime
import com.sy.mqhexsdk.bean.rec.RecTransmission
import com.sy.mqhexsdk.bean.rec.RecTransmissionResp
import com.sy.mqhexsdk.bean.rec.RecUpgradeBlock
import com.sy.mqhexsdk.bean.rec.RecUploadFuncListResult
import com.sy.mqhexsdk.bean.rec.RecUserInfo
import com.sy.mqhexsdk.bean.rec.RecUserInfoNew
import com.sy.mqhexsdk.bean.rec.RecVerifyDataResp
import com.sy.mqhexsdk.bean.rec.RecWifi
import com.sy.mqhexsdk.bean.rec.RecWithdrawalOrder
import com.sy.mqhexsdk.bean.rec.RecWithdrawalOrderNew
import com.sy.mqhexsdk.callback.ILogsCallback
import com.sy.mqhexsdk.callback.IMainCallback
import com.sy.mqhexsdk.manager.BaseManager
import com.sy.mqhexsdk.util.HexUtil
import com.sy.simpleegg.BuildConfig

class WhmMqttHex(
    private val context: Context,
    private val channelSum: Int,
    private val protocalVersion: String,
    private val clientId: String,
    private val hardwareCode: String,
    private val userName: String,
    private val password: String,
    private val host: String,
    private val authHost: String,
    private val platformCode: String,
    private val commonKey: String,
    private val privateKey: String,
    private val netInfoAction: () -> NetInfo?,
    private val signalInfoAction: () -> SignalInfo?,
    private val devType: Int = WhmHexDevType.UNIT_TYPE_COIN,//4-兑币机 5-售珠机
){
    private val TAG = javaClass.simpleName

    private var packageRequestCount: Long = 0

    private var packageNormalList: MutableList<WhmHexGoodBean> = mutableListOf()
    private var packageRechargeList: MutableList<WhmHexGoodBean> = mutableListOf()

    private var onMqttDataCallback: OnMqttDataCallback? = null

    private var codeType = 0

    private var loginTokenHex: String = ""

    init {
        try {
            WhmMqHexHplper.instance.runWithVersion(
                context,
                channelSum,
                protocalVersion,
                clientId,
                hardwareCode,
                userName,
                password,
                host,
                authHost,
                platformCode,
                commonKey,
                privateKey,
                {
                    netInfoAction.invoke()
                },
                {
                    signalInfoAction.invoke()
                },
                object : IMainCallback{
                    override fun authFail(statusCode: Int, errorMsg: String) {
                        logFile(
                            "设备校验失败：" +
                                    "\nstatusCode=$statusCode" +
                                    "\nerrorMsg=$errorMsg"
                        )
                    }

                    override fun bindDevice(businessCode: String, deviceQrcodeUrl: String?) {
                        logFile(
                            "设备 $businessCode 未绑定，请扫描二维码绑定设备：$deviceQrcodeUrl"
                        )
                        onMqttDataCallback?.onShowRegistCode(deviceQrcodeUrl?:"undefined")
                    }

                    override fun publishFinish(
                        success: Boolean,
                        topic: String?,
                        dataByts: ByteArray,
                        throwable: Throwable?
                    ) {
                        logFile(
                            "消息发送${if (success) "成功：" else "失败："}\n" +
                                    "主题：$topic\n" +
                                    "消息内容：${HexUtil.bytes2HexStr(dataByts)}" +
                                    if (throwable != null) "\n异常信息：${throwable.message}" else ""
                        )
                    }

                    override fun recAppVerResp(recAppVerResp: RecAppVerResp) {
                        logFile("收到APP版本信息：${GsonUtil.getInstance()?.toJson(recAppVerResp)}")
                        recAppVerResp.run {
                            verifyUpgradeVer(ver, verType, url)
                        }
                    }

                    override fun topicSubscribe(
                        success: Boolean,
                        topic: String?,
                        throwable: Throwable?
                    ) {
                        logFile(
                            "主题订阅${if (success) "成功" else "失败"}\n" +
                                    "主题：$topic" +
                                    if (throwable != null) "\n异常信息：${throwable.message}" else ""
                        )
                        onMqttDataCallback?.onMqttOpen()
                    }

                    override fun connectState(state: BaseManager.ConnectStates, throwable: Throwable?) {
                        logFile("连接状态：$state" + if (throwable != null) "\n异常信息：${throwable.message}" else "")
                    }

                    override fun onRecChannelGoodSingle(recChannelGood: MutableList<RecChannelGoodInfo>) {

                    }

                    override fun recLogin(recLogin: RecLoginResult) {
                        logFile("登录结果：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recLogin)}")
                        recLogin.run {
                            if (result){
                                onMqttDataCallback?.onLoginSuccess(devNumber, qrCode)
//                                onMqttDataCallback?.onDevConsumeCode(qrCode)
                            }
//                            verifyUpgradeVer(upgradeVer)
                        }
                    }

                    override fun recLogoutResp(recLogoutResp: RecLogoutResp) {
                        logFile("用户注销登录信息：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recLogoutResp)}")
                        recLogoutResp.run {
                            if (result){
                                loginTokenHex = ""
                                onMqttDataCallback?.onDevLogout()
                            }
                        }
                    }

                    override fun recFuncListInfo(recFuncListInfo: RecFuncListInfo) {
                        logFile("功能列表：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recFuncListInfo)}")
                        recFuncListInfo.run {
                            onMqttDataCallback?.onFuncListInfo(updateTime, totalSum, startSort, sum, infos, descHex)
                        }
                    }

                    override fun recUploadFuncResult(recUploadFuncListResult: RecUploadFuncListResult) {
                        logFile("上报功能列表响应：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recUploadFuncListResult)}")
                        recUploadFuncListResult.run {
                            onMqttDataCallback?.onUploadFuncResult(sum, state)
                        }
                    }

                    override fun recUserInfo(recUserInfo: RecUserInfo) {
                        logFile("用户登录信息：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recUserInfo)}")
//                        recUserInfo.run {
//                            onMqttDataCallback?.onUserLogin(recUserInfo)
//                        }
                    }

                    override fun recUserInfoNew(recUserInfoNew: RecUserInfoNew) {
                        logFile("用户登录信息new：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recUserInfoNew)}")
                        recUserInfoNew.run {
                            loginTokenHex = loginToken
                            onMqttDataCallback?.onUserLogin(recUserInfoNew)
                        }
                    }

                    override fun recHeartBeat(recHeartBeatResult: RecHeartBeatResult) {
                        logFile("心跳响应：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recHeartBeatResult)}")
                        recHeartBeatResult.run {
                            onMqttDataCallback?.onHeartBeat(stateHex, success, descHex)
                        }
                    }

                    override fun recLogCommand(recLogCommand: RecLogCommand) {
                        logFile("收到上传日志指令：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recLogCommand)}")
                        recLogCommand.run {
                            onMqttDataCallback?.onRecLogCommand(logType, logNumber)
                        }
                    }

                    override fun recTime(recTime: RecTime) {
                        logFile("设备所在时区时间：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recTime)}")
                        recTime.run {
                            onMqttDataCallback?.onRecTime(recTime.time, recTime.timeZone)
                        }
                    }

                    override fun recShopInfo(recShopInfo: RecShopInfo) {
                        logFile("门店信息：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recShopInfo)}")
                        recShopInfo.run {
                            onMqttDataCallback?.onShopInfo(phoneNumber, shopName)
                        }
                    }

                    override fun recDeviceState(recDeviceStateResp: RecDeviceStateResp) {
                        logFile("上报设备状态响应：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recDeviceStateResp)}")
                        recDeviceStateResp.run {
                            onMqttDataCallback?.onDeviceStateResp(stateHex, descHex)
                        }
                    }

                    override fun recDownloadFile(recDownloadFile: RecDownloadFile) {
                        logFile("收到下载文件信息：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recDownloadFile)}")
//                        recDownloadFile.run {
//                            onMqttDataCallback?.onDownloadFile(recDownloadFile)
//                        }
//                        recDownloadFile.run {
//                            onMqttDataCallback?.onUpgradeApp(fileId, name, url)
//                        }
                    }

                    override fun recPackages(recPackageInfo: RecPackageInfo) {
                        logFile("套餐数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recPackageInfo)}")
                        recPackageInfo.run {
                            if (totalSum == 0 && pkgType == 1){
                                //设备套餐为0，获取充值套餐
                                packageNormalList = mutableListOf()
//                                getPackages(2, 0, 0, 0)
                                WhmMqHexHplper.instance.getPackages(2, 0, 0, 0)
                            }else if (totalSum == 0 && pkgType == 2){
                                //充值套餐为0
                                if (packageNormalList.isEmpty()){
                                    onMqttDataCallback?.refreshPackageData(mutableListOf())
                                }else{
//                                    val result: MutableList<WhmHexPackageBean> = mutableListOf()
//                                    packageNormalList.forEach { pkg ->
//                                        result.add(WhmHexPackageBean(
//                                            1,
//                                            pkg.pkgIdHex,
//                                            pkg.pkgName,
//                                            pkg.pkgUnit,
//                                            pkg.pkgAmount,
//                                            pkg.pkgRealAmount,
//                                            pkg.pkgDevUnit,
//                                            pkg.pkgValue,
//                                        ))
//                                    }
                                    val result = packageNormalList
                                    onMqttDataCallback?.refreshPackageData(result)
                                }
                            }else if (totalSum > 0 && pkgType == 1){
                                //设备套餐不为0，获取充值套餐
                                packageNormalList = mutableListOf()
                                pkgList.forEach { pkg ->
                                    packageNormalList.add(
                                        WhmHexGoodBean(
                                            1,
                                            pkg.pkgIdHex,
                                            pkg.pkgName,
                                            pkg.pkgUnit,
                                            pkg.pkgAmount,
                                            pkg.pkgRealAmount,
                                            pkg.pkgDevUnit,
                                            pkg.pkgValue
                                    ))
                                }
//                                getPackages(2, 0, 0, 0)
                                val result = packageNormalList
                                onMqttDataCallback?.refreshPackageData(result)
//                                WhmMqHexHplper.instance.getPackages(2, 0, 0, 0)
                            }else if (totalSum > 0 && pkgType == 2){
                                //充值套餐不为0
                                packageRechargeList = mutableListOf()
                                pkgList.forEach { pkg ->
                                    packageRechargeList.add(
                                        WhmHexGoodBean(
                                            2,
                                            pkg.pkgIdHex,
                                            pkg.pkgName,
                                            pkg.pkgUnit,
                                            pkg.pkgAmount,
                                            pkg.pkgRealAmount,
                                            pkg.pkgDevUnit,
                                            pkg.pkgValue
                                        ))
                                }
                                val result: MutableList<WhmHexGoodBean> = mutableListOf()
                                result.addAll(packageNormalList)
                                result.addAll(packageRechargeList)
                                onMqttDataCallback?.refreshPackageData(result)
                            }else{
                                logFile("获取套餐数据错误：${GsonUtil.getInstance()!!.toJson(this)}")
                            }
                        }
                    }

                    override fun recPackagesById(recPackageByIdInfo: RecPackageByIdInfo) {
                        logFile("指定ID的套餐数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recPackageByIdInfo)}")
                        recPackageByIdInfo.run {
                            val pkgDataList: MutableList<WhmHexGoodBean> = mutableListOf()
                            pkgList.forEach { pkg ->
                                pkgDataList.add(WhmHexGoodBean(
                                    -1,
                                    pkg.pkgIdHex,
                                    pkg.pkgName,
                                    pkg.pkgUnit,
                                    pkg.pkgAmount,
                                    pkg.pkgRealAmount,
                                    pkg.pkgDevUnit,
                                    pkg.pkgValue,
                                ))
                            }
                            onMqttDataCallback?.onPackageById(pkgType, pkgDataList)
                        }
                    }

                    override fun recPackagesUpdate(recPackageUpdate: RecPackageUpdate) {
                        logFile("套餐数据更新指令：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recPackageUpdate)}")
                        recPackageUpdate.run {
                            onMqttDataCallback?.onPackagesUpdate(pkgType, totalSum, updateIdHexList)
                        }
                    }

                    override fun recPayTypeList(recPayTypeList: RecPayTypeList) {
                        logFile("支付方式数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recPayTypeList)}")
                        recPayTypeList.run {
                            val payTypeDataList: MutableList<WhmHexPayTypeBean> = mutableListOf()
                            payTypeList.forEach { payType ->
                                payTypeDataList.add(
                                    WhmHexPayTypeBean(
                                    payType.id,
                                    payType.name
                                )
                                )
                            }
                            onMqttDataCallback?.onPayTypeList(totalSum, startSort, sum, payTypeDataList)
                        }
                    }

                    override fun recPayTypeListIcon(recPayTypeList: RecPayTypeList) {
                        logFile("支付方式(带图标)数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recPayTypeList)}")
                        recPayTypeList.run {
                            val payTypeDataList: MutableList<WhmHexPayTypeBean> = mutableListOf()
                            payTypeList.forEach { payType ->
                                payTypeDataList.add(
                                    WhmHexPayTypeBean(
                                        payType.id,
                                        payType.name,
                                        payType.icon
                                    )
                                )
                            }
                            onMqttDataCallback?.onPayTypeList(totalSum, startSort, sum, payTypeDataList)
                        }
                    }

                    override fun recPayCode(recPayCode: RecPayCode) {
                        logFile("支付二维码数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recPayCode)}")
                        recPayCode.run {
                            onMqttDataCallback?.onPayCode(sn, codeData)
                        }
                    }

                    override fun recCodePayResult(recCodePayResult: RecCodePayResult) {
                        logFile("二维码支付结果数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recCodePayResult)}")
                        recCodePayResult.run {
                            onMqttDataCallback?.onCodePayResult(sn, payResult)
                        }
                    }

                    override fun recDevConsumeWalletResp(recDevConsumeWalletResp: RecDevConsumeWalletResp) {
                        logFile("设备消费用户钱包响应数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recDevConsumeWalletResp)}")

                    }

                    override fun recDevQrCode(recDevQrCode: RecDevQrCode) {
                        logFile("收到设备登录二维码数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recDevQrCode)}")
                        recDevQrCode.run {
                            when {
                                codeType == 1 -> onMqttDataCallback?.onDevLoginQrCode(code)
                                codeType == 2 -> onMqttDataCallback?.onWithdrawalCode(code)
                                else -> {

                                }
                            }
                        }
                        codeType = 0
                    }

                    override fun recDevSaveWalletResp(recDevSaveWalletResp: RecDevSaveWalletResp) {
                        logFile("上报设备存入钱包响应数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recDevSaveWalletResp)}")
                    }

                    override fun recDeviceErrStateResp(recDeviceErrStateResp: RecDeviceErrStateResp) {
                        logFile("上报设备故障响应数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recDeviceErrStateResp)}")
                        recDeviceErrStateResp.run {
                            onMqttDataCallback?.onDeviceErrStateResp(type, lv, errCode, state)
                        }
                    }

                    override fun recReverseData(recReverseDataResp: RecReverseDataResp) {
                        logFile("上报反扫数据响应：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recReverseDataResp)}")
                        recReverseDataResp.run {
                            onMqttDataCallback?.onReverseData(dataLen)
                        }
                    }

                    override fun recSaveCoinsResp(recSaveCoinsResp: RecSaveCoinsResp) {
                        logFile("上报存币响应数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recSaveCoinsResp)}")
                        recSaveCoinsResp.run {
                            onMqttDataCallback?.onSaveCoinResp(recSaveCoinsResp.result)
                        }
                    }

                    override fun recVerifyDataResp(recVerifyDataResp: RecVerifyDataResp) {
                        logFile("上报核销数据响应：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recVerifyDataResp)}")
                        recVerifyDataResp.run {
                            onMqttDataCallback?.onVerifyDataResp(dataLen, result, errMsg)
                        }
                    }

                    override fun recSwipeCardDataResp(recSwipeCardDataResp: RecSwipeCardDataResp) {
                        logFile("上报刷卡数据响应：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recSwipeCardDataResp)}")
                        recSwipeCardDataResp.run {
                            onMqttDataCallback?.onSwipeCardDataResp(dataLen)
                        }
                    }

                    override fun recUpgradeBlock(recUpgradeBlock: RecUpgradeBlock) {
                        logFile("更新包分包数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recUpgradeBlock)}")
                        recUpgradeBlock.run {
                            onMqttDataCallback?.onUpgradeBlock(totalBlock, blockSort, blockDataHex)
                        }
                    }

                    override fun recForceUpgrade(recForceUpgrade: RecForceUpgrade) {
                        logFile("强制更新数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recForceUpgrade)}")
                        recForceUpgrade.run {
                            onMqttDataCallback?.onForceUpgrade(upgradeVer)
                        }
                    }

                    override fun recCashDataResp(recCashDataResp: RecCashDataResp) {
                        logFile("投钞数据响应：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recCashDataResp)}")
                        recCashDataResp.run {
                            onMqttDataCallback?.onCashDataResp(result, successPkgSum)
                        }
                    }

                    override fun recChannelGood(
                        type: Int,
                        recChannelGood: MutableList<RecChannelGoodInfo>,
                    ) {
                        logFile("货道数据：type=$type ${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recChannelGood)}")
                    }

                    override fun recChannelGoodOrder(recOrder: RecChannelGoodOrder) {
                        logFile("收到货道商品订单：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recOrder)}")
                    }

                    override fun recChannelParamResp(recChannelParamResp: RecChannelParamResp) {
                        logFile("上报货道参数响应：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recChannelParamResp)}")
                    }

                    override fun recChannelPayCode(recPayCode: RecPayCode) {
                        logFile("收到货道商品支付二维码：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recPayCode)}")
                    }

                    override fun recCheckChannel(recCheckChannel: RecCheckChannel) {
                        logFile("查询货道参数结果：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recCheckChannel)}")
                    }

                    override fun recReboot(recReboot: RecReboot) {
                        logFile("重启指令：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recReboot)}")
                        recReboot.run {
                            onMqttDataCallback?.onReboot(msg)
                        }
                    }

                    override fun recReloadChannelGood(recReloadChannelGood: RecReloadChannelGood) {
                        logFile("收到更新货道商品数据指令：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recReloadChannelGood)}")
                    }

                    override fun recWifi(recWifi: RecWifi) {
                        logFile("配置WIFI指令：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recWifi)}")
                        recWifi.run {
                            onMqttDataCallback?.onWifi(ssid, pwd)
                        }
                    }

//                    override fun recWithdrawalCode(recWithdrawalCode: RecWithdrawalCode) {
//                        logFile("收到提币二维码：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recWithdrawalCode)}")
//                        recWithdrawalCode.run {
//                            onMqttDataCallback?.onWithdrawalCode(code)
//                        }
//                    }

                    override fun recWithdrawalOrder(recWithdrawalOrder: RecWithdrawalOrder) {
                        logFile("收到提币订单：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recWithdrawalOrder)}")
                        recWithdrawalOrder.run {
                            onMqttDataCallback?.onWithdrawalOrder(orderNumber, coins, accountCoins, measurementUnit)
                        }
                    }

                    override fun recWithdrawalOrderNew(recWithdrawalOrderNew: RecWithdrawalOrderNew) {
                        logFile("收到提币订单new：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recWithdrawalOrderNew)}")
                        recWithdrawalOrderNew.run {
                            if (devType != amountUnit) {
                                logFile("订单类型与设备类型不匹配，设备类型 $devType 订单单位类型 $amountUnit")
                                return@run
                            }
                            onMqttDataCallback?.onWithdrawalOrderNew(userId, walletType, orderNumber, amount, amountUnit, balance)
                        }
                    }

                    override fun recOrder(recOrder: RecOrder) {
                        logFile("收到订单数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recOrder)}")
                        recOrder.run {
                            onMqttDataCallback?.receiveOrder(sn, value, unit, payType, amount, accountRemainAmount, payMoneyUnit)
                        }
                    }

                    override fun recCheckOrder(recCheckOrder: RecCheckOrder) {
                        logFile("收到查询订单信息：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recCheckOrder)}")
                        recCheckOrder.run {
                            onMqttDataCallback?.onCheckOrder(sn)
                        }
                    }

                    override fun recTransmission(recTransmission: RecTransmission) {
                        logFile("收到透传数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recTransmission)}")
                        recTransmission.run {
                            onMqttDataCallback?.onTransmission(dataLen, dataHex)
                        }
                    }

                    override fun recTransmissionResp(recTransmissionResp: RecTransmissionResp) {
                        logFile("收到上报透传数据响应：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recTransmissionResp)}")
                        recTransmissionResp.run {
                            onMqttDataCallback?.onTransmissionResp(accessDataByteSum)
                        }
                    }

                    override fun recCmdData(recCmdNumberData: RecCmdNumberData) {
                        logFile("收到透传指令编号数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recCmdNumberData)}")
                        recCmdNumberData.run {
                            onMqttDataCallback?.onCmdNumberData(cmdNumber, dataLen, dataHex)
                        }
                    }

                    override fun recCmdDataResp(recCmdNumberDataResp: RecCmdNumberDataResp) {
                        logFile("收到上报透传指令编号数据响应：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recCmdNumberDataResp)}")
                        recCmdNumberDataResp.run {
                            onMqttDataCallback?.onCmdNumberDataResp(cmdNumber, accessDataByteSum)
                        }
                    }

                    override fun recGoodSingle(recGoodSingle: RecGoodSingle) {
                        logFile("收到单个商品数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recGoodSingle)}")
                        recGoodSingle.run {
                            onMqttDataCallback?.onGoodSingle(goodId, goodPrice, priceUnit, stock, update)
                        }
                    }

                    override fun recGoodStockResp(recGoodStockResp: RecGoodStockResp) {
                        logFile("收到商品库存更新响应数据：${com.sy.mqhexsdk.util.GsonUtil.instance().toJson(recGoodStockResp)}")
                        recGoodStockResp.run {
                            onMqttDataCallback?.onGoodStockResp(result, updateType, afterStock, update)
                        }
                    }
                },
                object : ILogsCallback{
                    override fun log(msg: String?) {
                        
                    }

                }
            )
        }catch (e: Exception){
            e.printStackTrace()
            log("mqtt异常：${e.message}")
        }
    }

    /**
     * 设备登录
     * @param netType 接入网络类型 1-4G 2-WIFI
     * @param appVer APP版本
     * @param iccid SIM 卡 iccid
     * @param moduleVer 通讯模块版本号
     * @param pcbVer pcb版本号
     * @param localPosition 基站信息
     */
    fun login(netType: Int, appVer: String, iccid: String, moduleVer: String, pcbVer: String, localPosition: String){
        WhmMqHexHplper.instance.loginP(netType, appVer, iccid, moduleVer, pcbVer, localPosition)
    }

    /**
     * 查询功能列表
     * @param sort 用于表示当前查询的功能序号
     * @param sum 用于表示本次查询查多少个功能信息
     * 当功能序号、查询的功能数量均为0时，服务器仅返回该设备的功能数量总数，不返回详细信息
     */
    fun getFuncList(sort: Int, sum: Int){
        WhmMqHexHplper.instance.getFuncList(sort, sum)
    }

    /**
     * 获取设备所在时区当前时间
     * @param timeZone 时区
     */
    fun getTime(timeZone: String){
        WhmMqHexHplper.instance.getTime(timeZone)
    }

    /**
     * 查询设备所属门店数据
     */
    fun getShopInfo(){
        WhmMqHexHplper.instance.getShopInfo()
    }

    /**
     * 获取套餐
     * @param pkgType 套餐类型
     * @param totalSum 套餐总数
     * @param startSort 套餐起始序号
     * @param getPkgSum 本次返回的套餐数量
     */
    fun getPackages(){
        WhmMqHexHplper.instance.getPackages(1, 0, 1, 0)
    }

    /**
     * 获取指定套餐ID的套餐信息
     * @param pkgType 套餐类型
     * @param pkgSum 套餐总数
     * @param pkgIdsHex 套餐ID
     */
    fun getPackagesById(pkgType: Int, pkgSum: Int, pkgIdsHex: MutableList<String>){
        WhmMqHexHplper.instance.getPackagesById(pkgType, pkgSum, pkgIdsHex)
    }

    /**
     * 获取支付方式
     * @param totalSum 支付方式总数
     * @param startSort 起始序号
     * @param sum 本次查询的支付方式个数
     */
    fun getPayTypeList(totalSum: Int, startSort: Int, sum: Int){
        WhmMqHexHplper.instance.getPayTypeList(totalSum, startSort, sum)
    }

    /**
     * 获取支付二维码
     * @param pkgType 套餐类型
     * @param pkgIdHex 套餐id
     * @param payType 支付方式
     */
    fun getPayCode(pkgType: Int, pkgIdHex: String, payType: Int){
        WhmMqHexHplper.instance.getPayCode(pkgType, pkgIdHex, payType)
    }

    /**
     * 获取二维码支付结果
     * @param tokenHex
     * @param sn 订单号
     * @param payType 支付方式
     */
    fun getPayResult(sn: String, payType: Int){
        WhmMqHexHplper.instance.getPayResult(sn, payType)
    }

    /**
     * 上报设备故障
     * @param type 故障类型 1-支付盒子故障 2-终端硬件故障
     * @param lv 本次设备的故障级别 级别决定了是否推送通知
     * @param stopPay 是否需要暂停支付 0x00为恢复支付，其他值为暂停支付
     * @param errModule 决定了本次故障模板使用什么模板进行推送
     * @param errCode 终端设备自行定义的代码值 实际推送到用户消息时所带的代码，高位在前低位在后
     */
    fun repDevErr(type: Int, lv: Int, stopPay: Int, errModule: String, errCode: String){
        WhmMqHexHplper.instance.repDevErr(type, lv, stopPay, errModule, errCode)
    }

    /**
     * 上报反扫数据
     * @param tokenHex
     * @param pkgType 套餐类型
     * @param pkgIdHex 套餐id
     * @param payType 设备支付方式
     * @param data 反扫数据
     */
    fun repReverseData(
        pkgType: Int,
        pkgIdHex: String,
        payType: Int,
        data: String
    ){
        WhmMqHexHplper.instance.repReverseData(pkgType, pkgIdHex, payType, data)
    }

    /**
     * 上报核销数据
     * @param verifyType 核销类型
     * @param data 反扫核销码的数据
     */
    fun repVerifyData(verifyType: Int, data: String){
        WhmMqHexHplper.instance.repVerifyData(verifyType, data)
    }

    /**
     * 上报刷卡数据
     * @param pkgType 套餐类型
     * @param pkgIdHex 套餐id
     * @param payType 设备支付方式
     * @param data 刷卡数据
     */
    fun repSwipeCardData(
        pkgType: Int,
        pkgIdHex: String,
        payType: Int,
        data: String
    ){
        WhmMqHexHplper.instance.repSwipeCardData(pkgType, pkgIdHex, payType, data)
    }

    /**
     * 获取更新包数据
     * @param upgradeVer 新版本号
     * @param totalBlock 更新包分包总数量
     * @param blockSort 数据包序号
     */
    fun repUpgradeBlock(upgradeVer: String, totalBlock: Long, blockSort: Long){
        WhmMqHexHplper.instance.repUpgradeBlock(upgradeVer, totalBlock, blockSort)
    }

    /**
     * 上报投钞数据
     * @param cashList 投钞数据
     */
    fun repCashData(cashList: MutableList<CashDataBean>, isNewProtocol: Boolean = false){
        if (isNewProtocol) {
            cashList.forEach {
                it.type = when (it.type){
                    1 -> "11".toInt(16)
                    2 -> "12".toInt(16)
                    else -> "11".toInt(16)
                }
            }
        }
        WhmMqHexHplper.instance.repCashData(cashList)
    }

    /**
     * 上报存币数据
     * @param userId 用户钱包id
     * @param coinList 存币数据
     */
    fun repSaveCoinsData(userId: String, coinList: MutableList<CoinsDataBean>){
        WhmMqHexHplper.instance.repSaveCoins(userId, coinList)
    }

    /**
     * 上报投钞数据
     * @param sn 订单号
     * @param doneValue 已处理数值(已出货数量)
     * @param result 结果 1-成功 2-失败
     * @param resultReason 该笔订单的结果原因 1-终端设备通讯异常 2-终端设备故障 3-其他
     */
    fun repOrderResult(sn: String, doneValue: Long, result: Int, resultReason: Int){
        WhmMqHexHplper.instance.repOrderResult(sn, doneValue, result, resultReason)
    }

    /**
     * 上报透传数据
     * @param dataHex 透传数据(16进制)
     */
    fun repTransmissionData(dataHex: String){
        WhmMqHexHplper.instance.repTransmissionData(dataHex)
    }

    /**
     * 上报透传指令编号数据
     * @param cmdNumber 指令编号
     * @param dataHex 透传数据(16进制)
     */
    fun repCmdNumberData(cmdNumber: String, dataHex: String){
        WhmMqHexHplper.instance.repCmdNumberData(cmdNumber, dataHex)
    }

    /**
     * 获取设备商品
     */
    fun getGoodSingle(){
        WhmMqHexHplper.instance.getGoodSingle()
    }

    /**
     * 更新商品库存
     * @param goodIdHex 商品id
     * @param updateType 更新类型 1-线上扫码支付出货 2-线下支付出货 3-设备本地清楚库存 4-设备本地补货 5-服务器线上修改库存
     * @param quantity 变化量
     * @param afterQuantity 变化后剩余库存
     * @param lastUpdate 上次更新时间戳
     * @param sn 订单 若无订单编号，则订单编号补0x31
     */
    fun repGoodStock(
        channelNumber: Int,
        goodIdHex: String,
        updateType: Int,
        quantity: Long,
        afterQuantity: Long,
        lastUpdate: Long,
        sn: String
    ){
        WhmMqHexHplper.instance.repGoodStock(channelNumber, goodIdHex, updateType, quantity, afterQuantity, lastUpdate, sn)
    }

    /**
     * 获取设备登录二维码
     */
    fun getLoginCode(){
        codeType = 1
        WhmMqHexHplper.instance.getDevQrCode(2, 0, 1)
    }

    /**
     * 获取提币二维码
     */
    fun getWithdrawalCode(direction: Int){
//        WhmMqHexHplper.instance.getWithdrawalCode()
        codeType = 2
        val dir = when (devType){
            WhmHexDevType.UNIT_TYPE_COIN -> 1//提币入口
            WhmHexDevType.UNIT_TYPE_BEAD -> 2//提珠入口
            else -> 1
        }
        WhmMqHexHplper.instance.getDevQrCode(2, dir, 1)
    }

    /**
     * 注销登录
     * @param loginTokenHex 用户登录token
     * @param logoutType 注销原因 0-手动注销 1-超时注销 2-他人登录注销
     */
    fun repLogout(loginTokenHex: String, logoutType: Int){
        if (this.loginTokenHex.isNotEmpty()) {
            WhmMqHexHplper.instance.repLogout(this.loginTokenHex, logoutType)
        }
    }

    /**
     * 上报终端设备处理线上消费结果
     * @param orderNumber 订单号
     * @param walletType 钱包类型 1-游戏机钱包 2-游艺钱包
     * @param amount 消费数量
     * @param amountUnit 消费数量单位
     * @param realAmount 实际消费数量
     * @param result 处理结果 1-成功 2-失败
     * @param msg 原因 1-终端设备通讯异常 2-终端设备故障 3-其他
     */
    fun repDevConsumeResult(orderNumber: String, amount: Long, amountUnit: Int, realAmount: Long, result: Int, msg: Int){
        WhmMqHexHplper.instance.repDevConsumeResult(orderNumber, 2, amount, devType, realAmount, result, msg)
    }

    /**
     * 设备主动消费用户钱包
     * @param loginTokenHex 用户登录token
     * @param userId 用户id
     * @param walletType 钱包类型 1-游戏机钱包 2-游艺钱包
     * @param consumeAmount 消费数量
     * @param amountUnit 消费数量单位
     * @param realConsumeAmount 实际消费数量
     * @param balance 剩余数量
     * @param addCode 自增码 新数据的时候自增 1-254循环
     * @param retry 重发的时候自增
     */
    fun repDevConsumeWallet(loginTokenHex: String, userIdHex: String, consumeAmount: Long, amountUnit: Int, realConsumeAmount: Long, balance: Long, addCode: Int, retry: Int){
        WhmMqHexHplper.instance.repDevConsumeWallet(loginTokenHex, userIdHex, 2, consumeAmount, devType, realConsumeAmount, balance, addCode, retry)
    }

    /**
     * 设备主动存入用户钱包
     * @param loginTokenHex 用户登录token
     * @param userIdHex 用户id
     * @param walletType 钱包类型 1-游戏机钱包 2-游艺钱包
     * @param consumeAmount 消费数量
     * @param amountUnit 消费数量单位
     * @param realConsumeAmount 实际消费数量
     * @param balance 剩余数量
     * @param addCode 自增码 新数据的时候自增 1-254循环
     * @param retry 重发的时候自增
     */
    fun repDevSaveWallet(loginTokenHex: String, userIdHex: String, consumeAmount: Long, amountUnit: Int, realConsumeAmount: Long, balance: Long, addCode: Int, retry: Int){
        WhmMqHexHplper.instance.repDevSaveWallet(loginTokenHex, userIdHex, 2, consumeAmount, devType, realConsumeAmount, balance, addCode, retry)
    }

    /**
     * 获取文件下载url
     * @param fileId 文件id(版本号)
     */
    fun getDownloadFileUrl(fileId: String){
        WhmMqHexHplper.instance.getDownloadFileUrl(fileId)
    }

    /**
     * 查询APP版本
     * @param cpuId
     */
    fun repCheckAppVer(cpuId: String){
        WhmMqHexHplper.instance.repCheckAppVer(BuildConfig.APP_TYPE, cpuId)
    }

    fun close(){
        WhmMqHexHplper.instance.close()
    }

    /**
     * 校验更新版本号
     * @param ver 需要更新的版本号
     */
    private fun verifyUpgradeVer(ver: String, verType: Int, url: String){
        try {
            if (ver.length != 8){
                logFile("版本号长度不足8个字符，版本校验失败")
                return
            }
            if (!ver.startsWith(Constant.VERSION_PREFIX)){
                logFile("版本号前缀不符合规则，版本校验失败")
                return
            }
            val localVer = BoardApiUtil.getVersionName(App.instance)
            if (localVer.isNullOrEmpty()){
                logFile("本地APP版本号异常，版本校验失败：$localVer")
                return
            }
            if (ver == localVer){
                logFile("本地APP版本与服务器最新版本相同，不需要更新APP")
                return
            }
            val verCode = ver.substring(4).toInt(16)
            val localVerCode = localVer.substring(4).toInt(16)
            if (verCode <= localVerCode){
                logFile("本地APP版本高于服务器最新版本，不需要更新APP")
                return
            }
            logFile("有新版本APP，准备更新......")
            onMqttDataCallback?.onUpgradeApp(ver, ver, url)
        }catch (e: Exception){
            e.printStackTrace()
        }
    }

    interface OnMqttDataCallback{
//        /**
//         * 订阅主题成功，执行登录指令
//         */
//        fun toLogin()
//
//        /**
//         * 链接状态改变
//         * @param connectState 链接状态
//         */
//        fun connectionChange(connectState: Boolean)
//
//        /**
//         * 重新登录
//         */
//        fun reLogin()

        /**
         * 显示未注册的cpuid
         * @param cpuId 设备注册id
         */
        fun onShowRegistCode(cpuId: String)

        /**
         * 登录成功
         */
        fun onLoginSuccess(devNumber: String, qrCode: String)

        /**
         * 刷新套餐数据
         */
        fun refreshPackageData(dataList: MutableList<WhmHexGoodBean>)

        /**
         * 投钞响应
         * @param sucess
         * @param billMsgNumber 消息编号
         */
        fun onBillResponse(sucess: Boolean, billMsgNumber: String)

        /**
         * 收到订单数据
         * @param orderEntity 订单实体
         * @param msg
         */
//        fun receiveOrder(orderEntity: OrderEntity, msg: String?)
        fun receiveOrder(sn: String, value: Long, unit: Int, payType: Int, amount: String, accountRemainAmount: String, payMoneyUnit: Int)

        /**
         * 响应收到提示信息
         */
        fun responseTips()

        /**
         * 显示提示
         * @param color 1-黑色 其他-红色
         * @param tips 内容
         */
        fun showTips(color: Int, tips: String)

        fun onFuncListInfo(updateTime: String, totalSum: Int, startSort: Int, sum: Int, infos: MutableList<String>, descHex: String)
        fun onUploadFuncResult(sum: Int, state: String)

        fun onHeartBeat(stateHex: String, success: Boolean, descHex: String)

        fun onRecTime(time: String, timeZone: String)

        fun onShopInfo(phoneNumber: String?, shopName: String?)

        fun onDeviceStateResp(stateHex: String, descHex: String)

        fun onPackageById(pkgType: Int, pkgList: MutableList<WhmHexGoodBean>)

        fun onPackagesUpdate(pkgType: Int, totalSum: Int, updateIdHexList: MutableList<String>)

        fun onPayTypeList(totalSum: Int, startSort: Int, sum: Int, payTypeList: MutableList<WhmHexPayTypeBean>)

        fun onPayCode(sn: String, codeData: String)

        fun onCodePayResult(sn: String, payResult: Int)

        fun onDeviceErrStateResp(type: Int, lv: Int, errCode: String, state: String)

        fun onReverseData(dataLen: Long)

        fun onSaveCoinResp(result: Boolean)

        fun onVerifyDataResp(dataLen: Long, result: Boolean, errMsg: String)

        fun onSwipeCardDataResp(dataLen: Long)

        fun onUpgradeBlock(totalBlock: Long, blockSort: Long, blockDataHex: String)

        fun onForceUpgrade(upgradeVer: String)

        fun onCashDataResp(result: Int, successPkgSum: Int)

        fun onReboot(msg: String)

        fun onWifi(ssid: String, pwd: String)

        fun onCheckOrder(sn: String)

        fun onTransmission(dataLen: Long, dataHex: String)

        fun onTransmissionResp(accessDataByteSum: Long)

        fun onCmdNumberData(cmdNumber: String, dataLen: Long, dataHex: String)

        fun onCmdNumberDataResp(cmdNumber: String, accessDataByteSum: Long)

        fun onGoodSingle(goodId: String, goodPrice: String, priceUnit: Int, stock: Long, update: String)

        fun onGoodStockResp(result: Int, updateType: Int, afterStock: Long, update: String)

        fun onMqttOpen()

//        fun onUserLogin(recUserInfo: RecUserInfo)
        fun onUserLogin(recUserInfoNew: RecUserInfoNew)

        fun onDownloadFile(recDownloadFile: RecDownloadFile)

        fun onDevLoginQrCode(code: String)

        fun onDevConsumeCode(code: String)

        fun onDevLogout()

        fun onWithdrawalCode(code: String)

        fun onWithdrawalOrder(orderNumber: String, withdrawalCoins: Long, accountCoins: Long, measurementUnit: Int)

        fun onWithdrawalOrderNew(userId: String, walletType: Int, orderNumber: String, amount: String, amountUnit: Int, balance: String)

        fun onUpgradeApp(fileId: String, name: String, url: String)

        fun onRecLogCommand(logType: Int, logNumber: String)
    }

    fun setCallback(callback: OnMqttDataCallback){
        onMqttDataCallback = callback
    }

    private fun log (msg: String){
        Log.d(TAG, msg)
        Logger.d(msg)
    }
}